﻿package net.wangit.user.privilege;

import java.util.HashMap;
import java.util.Map;

import net.wangit.MapList;
import net.wangit.Row;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.util.DBHelper;
import net.wangit.support.SqlProvider;
import net.wangit.util.Checker;
import net.wangit.util.ClassUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class DataPrivilegeFactory {

	private static Log log = LogFactory
			.getLog(net.wangit.user.privilege.DataPrivilegeFactory.class);
	private static final String SQL_UNIT = "select t1.* from DP t1,UNIT t2 where t1.dpid=t2.dpid and t2.uid=? and t1.t!=2 order by t1.id";
	private static final String SQL_ENUMERATION = "select t1.* from DP t1,ENUMCONFIG t2 where t1.dpid=t2.dpid and t2.enumid=? order by t1.id";

	public DataPrivilegeFactory() {
	}

	public static DataPrivilege getUnitDataPrivilege(String domain,
			String unitId) throws Exception {
		if (Checker.isEmpty(domain) || Checker.isEmpty(unitId)) {
			log.error((new StringBuilder(
					"empty arguments is not acceptable: domain=")).append(
					domain).append(" unitid=").append(unitId).toString());
			return null;
		} else {
			unitId = unitId.toLowerCase();
			return getDataPrivilege(domain, "3", unitId);
		}
	}

	public static DataPrivilege getEnumerationDataPrivilege(String domain,
			String eid) throws Exception {
		if (Checker.isEmpty(domain) || Checker.isEmpty(eid)) {
			log.error((new StringBuilder(
					"empty arguments is not acceptable: domain=")).append(
					domain).append(" eid=").append(eid).toString());
			return null;
		} else {
			eid = eid.toLowerCase();
			return getDataPrivilege(domain, "4", eid);
		}
	}

	private static DataPrivilege getDataPrivilege(String domain,
			String privilegeType, String resourceId) throws Exception {
		DataPrivilege dp = DataPrivilegeCache.get(domain, privilegeType,
				resourceId);
		if (dp == null) {
			dp = createDataPrivilege(domain, privilegeType, resourceId);
			DataPrivilegeCache.put(domain, privilegeType, resourceId, dp);
		}
		return dp;
	}

	private static DataPrivilege createDataPrivilege(String domain,
			String privilegeType, String resourceId) throws Exception {
		DB db = DBHelper.getDomainDB(domain);
		MapList list;
		if ("3".equals(privilegeType))
			list = db
					.query(
							"select t1.* from DP t1,UNIT t2 where t1.dpid=t2.dpid and t2.uid=? and t1.t!=2 order by t1.id",
							new String[] { resourceId }, new int[] { 2 });
		else
			list = db
					.query(
							"select t1.* from DP t1,ENUMCONFIG t2 where t1.dpid=t2.dpid and t2.enumid=? order by t1.id",
							new String[] { resourceId }, new int[] { 2 });
		if (Checker.isEmpty(list))
			return null;
		Map sqlPrivileges = new HashMap();
		Map valuePrivileges = new HashMap();
		String ids[] = new String[list.size()];
		String names[] = new String[list.size()];
		String titles[] = new String[list.size()];
		for (int i = 0; i < list.size(); i++) {
			Row row = list.getRow(i);
			String type = row.get("t");
			String id = row.get("id");
			id = getId4RolePrivilege(type, id);
			String expression = row.get("e");
			String privilegeKey = PrivilegeUtil.getPrivilegeString(domain,
					privilegeType, resourceId, id);
			if ("1".equals(type))
				sqlPrivileges.put(privilegeKey, expression);
			else if ("2".equals(type))
				valuePrivileges.put(privilegeKey, expression);
			else
				try {
					SqlProvider provider = (SqlProvider) ClassUtil.loadClass(
							expression).newInstance();
					sqlPrivileges.put(privilegeKey, provider);
				} catch (Exception e) {
					log.error((new StringBuilder("SqlProvider error : "))
							.append(resourceId).append("(").append(expression)
							.append(")").toString());
					throw e;
				}
			ids[i] = id;
			names[i] = row.get("n");
			titles[i] = row.get("ar");
		}

		DataPrivilege dp = new DataPrivilege();
		dp.setSqlPrivileges(sqlPrivileges);
		dp.setValuePrivileges(valuePrivileges);
		dp.setIds(ids);
		dp.setNames(names);
		dp.setTitles(titles);
		return dp;
	}

	private static String getId4RolePrivilege(String type, String id) {
		return (new StringBuilder(String.valueOf(type))).append("_").append(id)
				.toString();
	}

}
